<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="theme-color" content="#0078E7"><meta name="author" content="爱肖彤真是太好了"><meta name="copyright" content="爱肖彤真是太好了"><meta name="generator" content="Hexo 5.1.1"><meta name="theme" content="hexo-theme-yun"><title>go 结构体、方法、接口 | 工藤旧二の博客</title><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@900&amp;display=swap" media="none" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/star-markdown-css@0.1.19/dist/yun/yun-markdown.min.css"><script src="//at.alicdn.com/t/font_1140697_stqaphw3j4.js" async></script><script src="https://cdn.jsdelivr.net/npm/scrollreveal/dist/scrollreveal.min.js" defer></script><script>document.addEventListener("DOMContentLoaded", () => {
  [".post-card",".post-content img"].forEach((target)=> {
    ScrollReveal().reveal(target);
  })
});
</script><link rel="shortcut icon" type="image/svg+xml" href="/task/yun.ico"><link rel="mask-icon" href="/task/yun.ico" color="#0078E7"><link rel="alternate icon" href="/yun.ico"><link rel="preload" href="/task/css/hexo-theme-yun.css" as="style"><link rel="preload" href="/task/js/utils.js" as="script"><link rel="preload" href="/task/js/hexo-theme-yun.js" as="script"><link rel="prefetch" href="/task/js/sidebar.js" as="script"><link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin><link rel="stylesheet" href="/task/css/hexo-theme-yun.css"><link rel="alternate" href="/task/atom.xml" title="工藤旧二の博客" type="application/atom+xml"><script id="yun-config">
    const Yun = window.Yun || {};
    window.CONFIG = {"root":"/task/","title":"工藤旧二の博客","version":"0.9.7","anonymous_image":"https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/avatar/none.jpg","say":{"api":"https://v1.hitokoto.cn","hitokoto":true},"local_search":{"path":"/task/search.xml"},"fireworks":{"colors":["102, 167, 221","62, 131, 225","33, 78, 194"]}};
  </script><script>(function(){
  var bp = document.createElement('script');
  var curProtocol = window.location.protocol.split(':')[0];
  if (curProtocol === 'https') {
    bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
  }
  else {
    bp.src = 'http://push.zhanzhang.baidu.com/push.js';
  }
  var s = document.getElementsByTagName("script")[0];
  s.parentNode.insertBefore(bp, s);
})();</script><meta name="description" content="1 结构体定义：结构体是多个字段的集合 面向对象中类的定义是属性和方法的集合，结构体可以看做是属性的集合 1.1 结构体定义（创建命名结构体）&#x2F;&#x2F; type关键字 结构体名 struct关键字{} type People struct {     name string     &#x2F;&#x2F; 如果是大写开头表示可以在作为包导入中引用     Age int     sex string } func ma">
<meta property="og:type" content="article">
<meta property="og:title" content="go 结构体、方法、接口">
<meta property="og:url" content="http://huang_zhao.gitee.io/task/2020/09/14/go/%E5%9F%BA%E7%A1%80/go%20%E7%BB%93%E6%9E%84%E4%BD%93%E3%80%81%E6%96%B9%E6%B3%95%E3%80%81%E6%8E%A5%E5%8F%A3/index.html">
<meta property="og:site_name" content="工藤旧二の博客">
<meta property="og:description" content="1 结构体定义：结构体是多个字段的集合 面向对象中类的定义是属性和方法的集合，结构体可以看做是属性的集合 1.1 结构体定义（创建命名结构体）&#x2F;&#x2F; type关键字 结构体名 struct关键字{} type People struct {     name string     &#x2F;&#x2F; 如果是大写开头表示可以在作为包导入中引用     Age int     sex string } func ma">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-09-14T14:47:11.000Z">
<meta property="article:modified_time" content="2020-09-14T13:58:07.000Z">
<meta property="article:author" content="爱肖彤真是太好了">
<meta property="article:tag" content="go">
<meta property="article:tag" content="go面向接口">
<meta name="twitter:card" content="summary"><script src="/task/js/ui/mode.js"></script><link rel="stylesheet" href="/task/css/prism.css" type="text/css"></head><body><script defer src="https://cdn.jsdelivr.net/npm/animejs@latest/anime.min.js"></script><script defer src="/task/js/ui/fireworks.js"></script><canvas class="fireworks"></canvas><div class="container"><a class="sidebar-toggle hty-icon-button" id="menu-btn"><div class="hamburger hamburger--spin" type="button"><span class="hamburger-box"><span class="hamburger-inner"></span></span></div></a><div class="sidebar-toggle sidebar-overlay"></div><aside class="sidebar"><script src="/task/js/sidebar.js"></script><ul class="sidebar-nav"><li class="sidebar-nav-item sidebar-nav-toc hty-icon-button sidebar-nav-active" data-target="post-toc-wrap" title="文章目录"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-list-ordered"></use></svg></li><li class="sidebar-nav-item sidebar-nav-overview hty-icon-button" data-target="site-overview-wrap" title="站点概览"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-passport-line"></use></svg></li></ul><div class="sidebar-panel" id="site-overview-wrap"><div class="site-info fix-top"><a class="site-author-avatar" href="/task/about/" title="爱肖彤真是太好了"><img width="96" loading="lazy" src="/task/Yun.png" alt="爱肖彤真是太好了"></a><div class="site-author-name"><a href="/task/about/">爱肖彤真是太好了</a></div><a class="site-name" href="/task/about/site.html">工藤旧二の博客</a><sub class="site-subtitle"></sub><div class="site-desciption"></div></div><nav class="site-state"><a class="site-state-item hty-icon-button icon-home" href="/task/" title="首页"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-home-4-line"></use></svg></span></a><div class="site-state-item"><a href="/task/archives/" title="归档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-archive-line"></use></svg></span><span class="site-state-item-count">57</span></a></div><div class="site-state-item"><a href="/task/categories/" title="分类"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-2-line"></use></svg></span><span class="site-state-item-count">2</span></a></div><div class="site-state-item"><a href="/task/tags/" title="标签"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="site-state-item-count">50</span></a></div><a class="site-state-item hty-icon-button" target="_blank" rel="noopener" href="https://yun.yunyoujun.cn" title="文档"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-settings-line"></use></svg></span></a></nav><hr style="margin-bottom:0.5rem"><div class="links-of-author"><a class="links-of-author-item hty-icon-button" rel="noopener" title="RSS" target="_blank" style="color:orange"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-rss-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="QQ" target="_blank" style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="GitHub" target="_blank" style="color:#6e5494"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-github-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="微博" target="_blank" style="color:#E6162D"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-weibo-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="豆瓣" target="_blank" style="color:#007722"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-douban-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://music.163.com/#/user/home?id=552858287" title="网易云音乐" target="_blank" style="color:#C20C0C"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-netease-cloud-music-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="知乎" target="_blank" style="color:#0084FF"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-zhihu-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" href="https://space.bilibili.com/15081363" title="哔哩哔哩" target="_blank" style="color:#FF8EB3"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-bilibili-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Twitter" target="_blank" style="color:#1da1f2"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-twitter-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Telegram Channel" target="_blank" style="color:#0088CC"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-telegram-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="E-Mail" target="_blank" style="color:#8E71C1"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-mail-line"></use></svg></a><a class="links-of-author-item hty-icon-button" rel="noopener" title="Travelling" target="_blank" style="color:var(--hty-text-color)"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-send-plane-2-line"></use></svg></a></div><hr style="margin:0.5rem 1rem"><div class="links"><a class="links-item hty-icon-button" href="/task/links/" title="我的小伙伴们" style="color:dodgerblue"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-genderless-line"></use></svg></a></div><br><a class="links-item hty-icon-button" id="toggle-mode-btn" href="javascript:;" title="Mode" style="color: #f1cb64"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-contrast-2-line"></use></svg></a></div><div class="sidebar-panel sidebar-panel-active" id="post-toc-wrap"><div class="post-toc"><div class="post-toc-content"><ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-%E7%BB%93%E6%9E%84%E4%BD%93"><span class="toc-text">1 结构体</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-1-%E7%BB%93%E6%9E%84%E4%BD%93%E5%AE%9A%E4%B9%89%EF%BC%88%E5%88%9B%E5%BB%BA%E5%91%BD%E5%90%8D%E7%BB%93%E6%9E%84%E4%BD%93%EF%BC%89"><span class="toc-text">1.1 结构体定义（创建命名结构体）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-2-%E5%88%9B%E5%BB%BA%E5%8C%BF%E5%90%8D%E7%BB%93%E6%9E%84%E4%BD%93"><span class="toc-text">1.2 创建匿名结构体</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-3-%E8%AE%BF%E9%97%AE-%E4%BF%AE%E6%94%B9%E7%BB%93%E6%9E%84%E4%BD%93%E5%AD%97%E6%AE%B5"><span class="toc-text">1.3 访问&#x2F;修改结构体字段</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-4-%E7%BB%93%E6%9E%84%E4%BD%93%E6%8C%87%E9%92%88"><span class="toc-text">1.4 结构体指针</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-5-%E5%8C%BF%E5%90%8D%E5%AD%97%E6%AE%B5"><span class="toc-text">1.5 匿名字段</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-6-%E5%B5%8C%E5%A5%97%E7%BB%93%E6%9E%84%E4%BD%93"><span class="toc-text">1.6 嵌套结构体</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-7-%E5%AD%97%E6%AE%B5%E6%8F%90%E5%8D%87"><span class="toc-text">1.7 字段提升</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-8-%E7%BB%93%E6%9E%84%E4%BD%93%E7%9B%B8%E7%AD%89%E6%80%A7"><span class="toc-text">1.8 结构体相等性</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-%E6%96%B9%E6%B3%95"><span class="toc-text">2 方法</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-1-%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AA%E6%96%B9%E6%B3%95"><span class="toc-text">1.1 定义一个方法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-2-%E5%87%BD%E6%95%B0%E8%83%BD%E5%AE%9E%E7%8E%B0%E5%90%8C%E6%A0%B7%E7%9A%84%E5%8A%9F%E8%83%BD%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A6%81%E6%96%B9%E6%B3%95%EF%BC%9F"><span class="toc-text">1.2 函数能实现同样的功能，为什么要方法？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-3-%E6%8C%87%E9%92%88%E6%8E%A5%E6%94%B6%E5%99%A8%E4%B8%8E%E5%80%BC%E6%8E%A5%E6%94%B6%E5%99%A8"><span class="toc-text">1.3 指针接收器与值接收器</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#1-4-%E9%9D%9E%E7%BB%93%E6%9E%84%E4%BD%93%E6%96%B9%E6%B3%95"><span class="toc-text">1.4 非结构体方法</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-%E6%8E%A5%E5%8F%A3"><span class="toc-text">3 接口</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#3-1-%E6%8E%A5%E5%8F%A3%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%EF%BC%88%E9%B8%AD%E5%AD%90%E7%B1%BB%E5%9E%8B%EF%BC%89%EF%BC%88%E9%9D%9E%E4%BE%B5%E5%85%A5%E5%BC%8F%EF%BC%89"><span class="toc-text">3.1 接口简单实现（鸭子类型）（非侵入式）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-2-%E4%BE%B5%E5%85%A5%E5%BC%8F%E6%8E%A5%E5%8F%A3"><span class="toc-text">3.2 侵入式接口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-3-%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%86%85%E9%83%A8%E8%A1%A8%E7%A4%BA"><span class="toc-text">3.3 接口的内部表示</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-4-%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80"><span class="toc-text">3.4 类型断言</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-5-%E7%A9%BA%E6%8E%A5%E5%8F%A3"><span class="toc-text">3.5 空接口</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-7-%E5%AE%9E%E7%8E%B0%E5%A4%9A%E4%B8%AA%E6%8E%A5%E5%8F%A3"><span class="toc-text">3.7 实现多个接口</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-%E8%87%AA%E5%AE%9A%E4%B9%89%E9%9B%86%E5%90%88%E7%B1%BB%E5%9E%8B"><span class="toc-text">4 自定义集合类型</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-make%E5%92%8Cnew%E7%9A%84%E5%8C%BA%E5%88%AB"><span class="toc-text">5 make和new的区别</span></a></li></ol></div></div></div></aside><main class="sidebar-translate" id="content"><div id="post"><article class="post-block" itemscope itemtype="https://schema.org/Article"><link itemprop="mainEntityOfPage" href="http://huang_zhao.gitee.io/task/task/2020/09/14/go/%E5%9F%BA%E7%A1%80/go%20%E7%BB%93%E6%9E%84%E4%BD%93%E3%80%81%E6%96%B9%E6%B3%95%E3%80%81%E6%8E%A5%E5%8F%A3/"><span hidden itemprop="author" itemscope itemtype="https://schema.org/Person"><meta itemprop="name" content="爱肖彤真是太好了"><meta itemprop="description"></span><span hidden itemprop="publisher" itemscope itemtype="https://schema.org/Organization"><meta itemprop="name" content="工藤旧二の博客"></span><header class="post-header"><h1 class="post-title" itemprop="name headline">go 结构体、方法、接口</h1><div class="post-meta"><div class="post-time" style="display:block"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-calendar-line"></use></svg></span> <time title="创建时间：2020-09-14 22:47:11" itemprop="dateCreated datePublished" datetime="2020-09-14T22:47:11+08:00">2020-09-14</time></div><span class="post-count"><span class="post-symbolcount"><span class="post-meta-item-icon" title="本文字数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-file-word-line"></use></svg></span> <span title="本文字数">2.4k</span><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读时长"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-timer-line"></use></svg></span> <span title="阅读时长">10m</span></span></span><span class="post-busuanzi"><span class="post-meta-divider">-</span><span class="post-meta-item-icon" title="阅读次数"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg> <span id="busuanzi_value_page_pv"></span></span></span><div class="post-classify"><span class="post-category"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-folder-line"></use></svg></span> <span itemprop="about" itemscope itemtype="https://schema.org/Thing"><a class="category" href="/task/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/" style="--text-color:var(--hty-text-color)" itemprop="url" rel="index"><span itemprop="text">技术分享</span></a></span></span><span class="post-tag"><span class="post-meta-divider">-</span><a class="tag" href="/task/tags/go/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">go</span></a><a class="tag" href="/task/tags/go%E9%9D%A2%E5%90%91%E6%8E%A5%E5%8F%A3/" style="--text-color:var(--hty-text-color)"><span class="post-meta-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-price-tag-3-line"></use></svg></span><span class="tag-name">go面向接口</span></a></span></div></div></header><section class="post-body" itemprop="articleBody"><div class="post-content markdown-body" style="--smc-primary:#0078E7;"><h3 id="1-结构体"><a href="#1-结构体" class="headerlink" title="1 结构体"></a>1 结构体</h3><p>定义：结构体是多个字段的集合</p>
<p>面向对象中类的定义是属性和方法的集合，结构体可以看做是属性的集合</p>
<h4 id="1-1-结构体定义（创建命名结构体）"><a href="#1-1-结构体定义（创建命名结构体）" class="headerlink" title="1.1 结构体定义（创建命名结构体）"></a>1.1 结构体定义（创建命名结构体）</h4><pre class=" language-go"><code class="language-go"><span class="token comment" spellcheck="true">// type关键字 结构体名 struct关键字{}</span>
<span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    <span class="token comment" spellcheck="true">// 如果是大写开头表示可以在作为包导入中引用</span>
    Age <span class="token builtin">int</span>
    sex <span class="token builtin">string</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 两种定义方式，按位置必须全传，按关键字可以不按顺序少传</span>
    peo <span class="token operator">:=</span> People<span class="token punctuation">{</span><span class="token string">"hz"</span><span class="token punctuation">,</span><span class="token number">18</span><span class="token punctuation">,</span><span class="token string">"男"</span><span class="token punctuation">}</span>
    peo2 <span class="token operator">:=</span> People<span class="token punctuation">{</span>name<span class="token punctuation">:</span><span class="token string">"lxt"</span><span class="token punctuation">,</span>age<span class="token punctuation">:</span><span class="token number">19</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>补充：如果只定义不初始化内部只存在对应字段的零值</p>
<h4 id="1-2-创建匿名结构体"><a href="#1-2-创建匿名结构体" class="headerlink" title="1.2 创建匿名结构体"></a>1.2 创建匿名结构体</h4><p>匿名结构体通常在创建的时候就定义，一般只用一次，在整合多个数据类型的时候可以用，通常定义在方法内部或者结构体内部</p>
<pre class=" language-go"><code class="language-go">dog <span class="token operator">:=</span> <span class="token keyword">struct</span><span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span><span class="token punctuation">{</span>
    name<span class="token punctuation">:</span><span class="token string">"xxx"</span><span class="token punctuation">,</span>
    age<span class="token punctuation">:</span> <span class="token number">189</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>dog<span class="token punctuation">)</span></code></pre>
<h4 id="1-3-访问-修改结构体字段"><a href="#1-3-访问-修改结构体字段" class="headerlink" title="1.3 访问/修改结构体字段"></a>1.3 访问/修改结构体字段</h4><pre class=" language-go"><code class="language-go"><span class="token comment" spellcheck="true">// 直接.访问修改赋值</span>
<span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    sex <span class="token builtin">string</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    peo <span class="token operator">:=</span> People<span class="token punctuation">{</span><span class="token punctuation">}</span>
    peo<span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">19</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>peo<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="1-4-结构体指针"><a href="#1-4-结构体指针" class="headerlink" title="1.4 结构体指针"></a>1.4 结构体指针</h4><pre class=" language-go"><code class="language-go"><span class="token comment" spellcheck="true">// 指向结构体的指针，用法和结构体没差</span>
<span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    sex <span class="token builtin">string</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    peo <span class="token operator">:=</span> <span class="token operator">&amp;</span>People<span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">// 原本必须要写(*peo).age go内部支持简写</span>
    peo<span class="token punctuation">.</span>age <span class="token operator">=</span> <span class="token number">19</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>peo<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="1-5-匿名字段"><a href="#1-5-匿名字段" class="headerlink" title="1.5 匿名字段"></a>1.5 匿名字段</h4><pre class=" language-go"><code class="language-go"><span class="token comment" spellcheck="true">// 匿名字段本质就是把字段类型当名字一起使用</span>
<span class="token comment" spellcheck="true">// 但是同时只能存在一种类型，就是不能写俩string</span>
<span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    sex <span class="token builtin">string</span>
    <span class="token builtin">string</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    peo <span class="token operator">:=</span> <span class="token operator">&amp;</span>People<span class="token punctuation">{</span><span class="token punctuation">}</span>
    peo<span class="token punctuation">.</span><span class="token builtin">string</span> <span class="token operator">=</span> <span class="token string">"xxx"</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>peo<span class="token punctuation">.</span><span class="token builtin">string</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="1-6-嵌套结构体"><a href="#1-6-嵌套结构体" class="headerlink" title="1.6 嵌套结构体"></a>1.6 嵌套结构体</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    sex <span class="token builtin">string</span>
    Hobby Hobby
<span class="token punctuation">}</span>
<span class="token keyword">type</span> Hobby <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    hobbyId <span class="token builtin">int</span>
    hobbyName <span class="token builtin">string</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    peo <span class="token operator">:=</span> People<span class="token punctuation">{</span><span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">// 定义方式1</span>
    <span class="token comment" spellcheck="true">//peo.Hobby.hobbyId = 1</span>
    <span class="token comment" spellcheck="true">//peo.Hobby.hobbyName= "xxx"</span>

    <span class="token comment" spellcheck="true">// 定义方式2</span>
    peo<span class="token punctuation">.</span>Hobby <span class="token operator">=</span> Hobby<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">"xxx"</span><span class="token punctuation">}</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>peo<span class="token punctuation">.</span>Hobby<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="1-7-字段提升"><a href="#1-7-字段提升" class="headerlink" title="1.7 字段提升"></a>1.7 字段提升</h4><p>在<strong>不重名</strong>的情况下可以把嵌套在内部的结构体字段提升到外层结构体来使用，如果重名就会优先使用外层结构体的字段名</p>
<pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    sex <span class="token builtin">string</span>
    <span class="token comment" spellcheck="true">// 必须使用匿名嵌套结构体才能提升</span>
    Hobby
<span class="token punctuation">}</span>
<span class="token keyword">type</span> Hobby <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    hobbyId <span class="token builtin">int</span>
    hobbyName <span class="token builtin">string</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    peo <span class="token operator">:=</span> <span class="token operator">&amp;</span>People<span class="token punctuation">{</span><span class="token punctuation">}</span>
    peo<span class="token punctuation">.</span>Hobby <span class="token operator">=</span> Hobby<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">"xxx"</span><span class="token punctuation">}</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>peo<span class="token punctuation">.</span>hobbyName<span class="token punctuation">)</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>peo<span class="token punctuation">.</span>hobbyId<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="1-8-结构体相等性"><a href="#1-8-结构体相等性" class="headerlink" title="1.8 结构体相等性"></a>1.8 结构体相等性</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    peo1 <span class="token operator">:=</span> People<span class="token punctuation">{</span><span class="token string">"hz"</span><span class="token punctuation">,</span><span class="token number">18</span><span class="token punctuation">}</span>
    peo2 <span class="token operator">:=</span> People<span class="token punctuation">{</span><span class="token string">"hz"</span><span class="token punctuation">,</span><span class="token number">18</span><span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">// 两个字段稍微一点不同就是false</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>peo1 <span class="token operator">==</span> peo2<span class="token punctuation">)</span> <span class="token comment" spellcheck="true">// true</span>

<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">// 注意：结构体中只有全是值类型才能比较，如果存在引用类型比如切片，map这种引用类型就不能比较</span></code></pre>
<h3 id="2-方法"><a href="#2-方法" class="headerlink" title="2 方法"></a>2 方法</h3><p>方法就是在定义函数之前加一个特殊的接收器类型，接收器可以是结构体或者非结构体，接收器内部可以访问这个方法</p>
<h4 id="1-1-定义一个方法"><a href="#1-1-定义一个方法" class="headerlink" title="1.1 定义一个方法"></a>1.1 定义一个方法</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">// 为People结构体绑定了printName方法</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>p People<span class="token punctuation">)</span><span class="token function">printName</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 初始化一个结构体对象</span>
    peo <span class="token operator">:=</span> People<span class="token punctuation">{</span>name<span class="token punctuation">:</span> <span class="token string">"hz"</span><span class="token punctuation">}</span>
    peo<span class="token punctuation">.</span><span class="token function">printName</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="1-2-函数能实现同样的功能，为什么要方法？"><a href="#1-2-函数能实现同样的功能，为什么要方法？" class="headerlink" title="1.2 函数能实现同样的功能，为什么要方法？"></a>1.2 函数能实现同样的功能，为什么要方法？</h4><ul>
<li>go不是纯粹的面向对象的语言，go不支持类，方法是对应面向对象中对象的方法</li>
<li>一个方法可以绑定给多个不同的结构体，但是一个函数不能接受不同的结构体作为参数</li>
</ul>
<h4 id="1-3-指针接收器与值接收器"><a href="#1-3-指针接收器与值接收器" class="headerlink" title="1.3 指针接收器与值接收器"></a>1.3 指针接收器与值接收器</h4><p>如果是在方法中</p>
<p>有值接收器，那它可以接收值接收器和指针接收器</p>
<p>有指针接收器，那它可以接收值接收器和指针接收器</p>
<p>总结：不管方法的接收器是什么，都可以用值或者指针去接受，两种接收器的区别就是：值接收器是值传递，指针接收器是引用传递</p>
<pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> People <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token punctuation">(</span>p People<span class="token punctuation">)</span><span class="token function">printName</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>p<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">// 如果只是简单的值传递，那在内部改的值其实是一个copy的新值</span>
<span class="token comment" spellcheck="true">// 值接收器</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>p People<span class="token punctuation">)</span><span class="token function">changeName</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    p<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"lxt"</span>
<span class="token punctuation">}</span>

<span class="token comment" spellcheck="true">// 如果需要改动真的生效，就需要用到指针接收器</span>
<span class="token comment" spellcheck="true">// 指针接收器（全都用这个就行了）</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>p <span class="token operator">*</span>People<span class="token punctuation">)</span><span class="token function">changeName2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    p<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">"lxt"</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    peo <span class="token operator">:=</span> People<span class="token punctuation">{</span>name<span class="token punctuation">:</span> <span class="token string">"hz"</span><span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">//peo.changeName()  // 没有改原值</span>
    peo<span class="token punctuation">.</span><span class="token function">changeName2</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    peo<span class="token punctuation">.</span><span class="token function">printName</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="1-4-非结构体方法"><a href="#1-4-非结构体方法" class="headerlink" title="1.4 非结构体方法"></a>1.4 非结构体方法</h4><p>如果要对非结构体绑定方法，那这个非结构体必须是我们自己定义的类型或者重命名的类型</p>
<pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> MyInt <span class="token builtin">int</span>
<span class="token comment" spellcheck="true">// 注意在运算中类型必须一致才能运算</span>
<span class="token comment" spellcheck="true">// int不能传入结构体，必须重命名</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>i MyInt<span class="token punctuation">)</span><span class="token function">add</span><span class="token punctuation">(</span>x MyInt<span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>i<span class="token operator">+</span>x<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> i MyInt <span class="token operator">=</span> <span class="token number">5</span>
    i<span class="token punctuation">.</span><span class="token function">add</span><span class="token punctuation">(</span><span class="token number">6</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="3-接口"><a href="#3-接口" class="headerlink" title="3 接口"></a>3 接口</h3><p>接口就是一系列方法的集合，类似于面向对象中的多态，go语言的接口也支持鸭子类型</p>
<p>面向对象领域中，接口是指定义和规范一个子类的行为</p>
<h4 id="3-1-接口简单实现（鸭子类型）（非侵入式）"><a href="#3-1-接口简单实现（鸭子类型）（非侵入式）" class="headerlink" title="3.1 接口简单实现（鸭子类型）（非侵入式）"></a>3.1 接口简单实现（鸭子类型）（非侵入式）</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">"fmt"</span>

<span class="token keyword">type</span> Duck <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> TDuck <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> DDuck <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    salary <span class="token builtin">int</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token punctuation">(</span>t TDuck<span class="token punctuation">)</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"TDUCK"</span><span class="token punctuation">,</span>t<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>d DDuck<span class="token punctuation">)</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"DDUCK"</span><span class="token punctuation">,</span>d<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>t TDuck<span class="token punctuation">)</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"T EAT"</span><span class="token punctuation">,</span>t<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>d DDuck<span class="token punctuation">)</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"D EAT"</span><span class="token punctuation">,</span>d<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 让Tduck和Dduck都实现Duck接口</span>
    <span class="token comment" spellcheck="true">// 方式一：通过鸭子类型，写同样的方法</span>
    t <span class="token operator">:=</span>TDuck<span class="token punctuation">{</span><span class="token string">"hz"</span><span class="token punctuation">,</span><span class="token number">18</span><span class="token punctuation">}</span>
    t<span class="token punctuation">.</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    d<span class="token operator">:=</span>DDuck<span class="token punctuation">{</span><span class="token string">"lxt"</span><span class="token punctuation">,</span><span class="token number">19</span><span class="token punctuation">,</span><span class="token number">2000</span><span class="token punctuation">}</span>
    d<span class="token punctuation">.</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<h4 id="3-2-侵入式接口"><a href="#3-2-侵入式接口" class="headerlink" title="3.2 侵入式接口"></a>3.2 侵入式接口</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> Duck <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>t TDuck<span class="token punctuation">)</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"TDUCK"</span><span class="token punctuation">,</span>t<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>d DDuck<span class="token punctuation">)</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"DDUCK"</span><span class="token punctuation">,</span>d<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>t TDuck<span class="token punctuation">)</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"T EAT"</span><span class="token punctuation">,</span>t<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>d DDuck<span class="token punctuation">)</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"D EAT"</span><span class="token punctuation">,</span>d<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">type</span> TDuck <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> DDuck <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    salary <span class="token builtin">int</span>
<span class="token punctuation">}</span>


<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 让Tduck和Dduck都实现Duck接口</span>
    <span class="token comment" spellcheck="true">// 方式二：侵入式接口，接口方法没有，报错</span>
    <span class="token keyword">var</span> duck Duck
    t<span class="token operator">:=</span>TDuck<span class="token punctuation">{</span><span class="token string">"hz"</span><span class="token punctuation">,</span><span class="token number">18</span><span class="token punctuation">}</span>

    duck<span class="token operator">=</span>t
    duck<span class="token punctuation">.</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    d<span class="token operator">:=</span>DDuck<span class="token punctuation">{</span><span class="token string">"lxt"</span><span class="token punctuation">,</span><span class="token number">19</span><span class="token punctuation">,</span><span class="token number">2000</span><span class="token punctuation">}</span>
    duck <span class="token operator">=</span> d
    duck<span class="token punctuation">.</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<h4 id="3-3-接口的内部表示"><a href="#3-3-接口的内部表示" class="headerlink" title="3.3 接口的内部表示"></a>3.3 接口的内部表示</h4><p>我们可以把接口看作内部的一个元组 (type, value)。<br>type 是接口底层的具体类型（Concrete Type），而 value 是具体类型的值。</p>
<h4 id="3-4-类型断言"><a href="#3-4-类型断言" class="headerlink" title="3.4 类型断言"></a>3.4 类型断言</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">"fmt"</span>

<span class="token keyword">type</span> Duck <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>t TDuck<span class="token punctuation">)</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"TDUCK"</span><span class="token punctuation">,</span>t<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>d DDuck<span class="token punctuation">)</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"DDUCK"</span><span class="token punctuation">,</span>d<span class="token punctuation">.</span>name<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>t TDuck<span class="token punctuation">)</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"T EAT"</span><span class="token punctuation">,</span>t<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>d DDuck<span class="token punctuation">)</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"D EAT"</span><span class="token punctuation">,</span>d<span class="token punctuation">.</span>age<span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token keyword">type</span> TDuck <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> DDuck <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
    salary <span class="token builtin">int</span>
<span class="token punctuation">}</span>


<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 断言类型</span>
    <span class="token comment" spellcheck="true">// 把接口类型转换成结构体类型</span>

    <span class="token comment" spellcheck="true">// 定义了一个接口类型</span>
    <span class="token keyword">var</span> tduck Duck <span class="token operator">=</span> TDuck<span class="token punctuation">{</span><span class="token string">"hz"</span><span class="token punctuation">,</span><span class="token number">18</span><span class="token punctuation">}</span>
    <span class="token comment" spellcheck="true">// 断言这个值的类型，v为值，ok为判断的bool</span>
    <span class="token comment" spellcheck="true">// 如果断言失败，ok为false v为空值</span>
    v<span class="token punctuation">,</span>ok <span class="token operator">:=</span> tduck<span class="token punctuation">.</span><span class="token punctuation">(</span>TDuck<span class="token punctuation">)</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>v<span class="token punctuation">)</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>ok<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<p><strong>类型断言扩展</strong></p>
<pre class=" language-go"><code class="language-go"><span class="token comment" spellcheck="true">//5 类型选择(通过switch)</span>
<span class="token comment" spellcheck="true">//var duck Duck =TDuck{"egon","男",1,"刘亦菲"}</span>
<span class="token comment" spellcheck="true">////var duck Duck =PDuck{"egon","男",1}</span>
<span class="token comment" spellcheck="true">//test4(duck)</span>


<span class="token comment" spellcheck="true">//使用switch，选择成功，拿到结构体对象</span>
<span class="token comment" spellcheck="true">//func test4(duck Duck)  {</span>
<span class="token comment" spellcheck="true">//    switch v:=duck.(type) {</span>
<span class="token comment" spellcheck="true">//    case PDuck:</span>
<span class="token comment" spellcheck="true">//        fmt.Println(v.name)</span>
<span class="token comment" spellcheck="true">//        fmt.Println("我是普通鸭子")</span>
<span class="token comment" spellcheck="true">//    case TDuck:</span>
<span class="token comment" spellcheck="true">//        fmt.Println(v.wife)</span>
<span class="token comment" spellcheck="true">//        fmt.Println("我是唐老鸭")</span>
<span class="token comment" spellcheck="true">//    default:</span>
<span class="token comment" spellcheck="true">//        fmt.Println(v)</span>
<span class="token comment" spellcheck="true">//        fmt.Println("我是鸭子这个类")</span>
<span class="token comment" spellcheck="true">//</span>
<span class="token comment" spellcheck="true">//    }</span>
<span class="token comment" spellcheck="true">//}</span></code></pre>
<h4 id="3-5-空接口"><a href="#3-5-空接口" class="headerlink" title="3.5 空接口"></a>3.5 空接口</h4><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">"fmt"</span>

<span class="token keyword">type</span> Empty <span class="token keyword">interface</span> <span class="token punctuation">{</span>

<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 定义一个空接口</span>
    <span class="token comment" spellcheck="true">// 所有数据类型都实现了空接口，所以空接口可以接受任意类型的值</span>
    <span class="token keyword">var</span> e Empty
    a <span class="token operator">:=</span> <span class="token number">123</span>
    e <span class="token operator">=</span> a
    <span class="token comment" spellcheck="true">// 虽然可以接受任意类型，但是有一个缺点就是本身没有任何方法</span>
    <span class="token comment" spellcheck="true">// 所以要使用原来值类型的方法就必须类型断言回去，再使用</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span>
<span class="token punctuation">}</span></code></pre>
<p>同理，集合中也可以放入空接口来接收任意值</p>
<pre class=" language-go"><code class="language-go"><span class="token comment" spellcheck="true">//var a[3]Duck</span>
<span class="token comment" spellcheck="true">//a[1]=PDuck{}</span>
<span class="token comment" spellcheck="true">//a[2]=TDuck{}</span>
<span class="token comment" spellcheck="true">//var a map[string]interface{}= make(map[string]interface{})</span>
<span class="token comment" spellcheck="true">//a["name"]="lqz"</span>
<span class="token comment" spellcheck="true">//a["age"]=19</span>
<span class="token comment" spellcheck="true">//a["duck"]=PDuck{}</span></code></pre>
<h4 id="3-7-实现多个接口"><a href="#3-7-实现多个接口" class="headerlink" title="3.7 实现多个接口"></a>3.7 实现多个接口</h4><p>方式一：直接写方法就行</p>
<p>方式二：通过接口嵌套</p>
<pre class=" language-go"><code class="language-go"><span class="token keyword">type</span> Animal <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    <span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token function">sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token keyword">type</span> Duck <span class="token keyword">interface</span> <span class="token punctuation">{</span>
    Animal
    <span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>

<span class="token comment" spellcheck="true">//type Cat interface {</span>
<span class="token comment" spellcheck="true">//    Animal</span>
<span class="token comment" spellcheck="true">//    speak()</span>
<span class="token comment" spellcheck="true">//    run()</span>
<span class="token comment" spellcheck="true">//}</span>
<span class="token comment" spellcheck="true">//如果一个结构体实现duck接口</span>
<span class="token keyword">type</span> PDuck <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    sex <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>

<span class="token keyword">func</span> <span class="token punctuation">(</span>p PDuck<span class="token punctuation">)</span><span class="token function">speak</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>

<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>p PDuck<span class="token punctuation">)</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>

<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>p PDuck<span class="token punctuation">)</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>

<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>p PDuck<span class="token punctuation">)</span><span class="token function">eat</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token punctuation">{</span>

<span class="token punctuation">}</span>



<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>

    <span class="token comment" spellcheck="true">//1 实现多个接口</span>
    <span class="token comment" spellcheck="true">//var t TDuck=TDuck{}</span>
    <span class="token comment" spellcheck="true">//var a Animal</span>
    <span class="token comment" spellcheck="true">//var d Duck</span>
    <span class="token comment" spellcheck="true">////一旦转到某个接口上，只能使用接口的方法，自身属性和自身方法需要类型断言后才能使用</span>
    <span class="token comment" spellcheck="true">//a=t</span>
    <span class="token comment" spellcheck="true">//d=ta</span>
    <span class="token comment" spellcheck="true">//2 接口嵌套</span>
    <span class="token comment" spellcheck="true">//var a Animal</span>
    <span class="token comment" spellcheck="true">//var d Duck</span>
    <span class="token comment" spellcheck="true">//var c PDuck=PDuck{}</span>
    <span class="token comment" spellcheck="true">//a=c</span>
    <span class="token comment" spellcheck="true">//d=c</span>

    <span class="token comment" spellcheck="true">//3 接口的零值</span>
    <span class="token comment" spellcheck="true">//var a Animal   //nil 是引用类型</span>
    <span class="token comment" spellcheck="true">//fmt.Println(a)</span>


<span class="token punctuation">}</span></code></pre>
<h3 id="4-自定义集合类型"><a href="#4-自定义集合类型" class="headerlink" title="4 自定义集合类型"></a>4 自定义集合类型</h3><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token keyword">import</span> <span class="token string">"fmt"</span>

<span class="token comment" spellcheck="true">//定义MySet类型</span>
<span class="token keyword">type</span> MySet <span class="token keyword">map</span><span class="token punctuation">[</span><span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token builtin">bool</span>
<span class="token comment" spellcheck="true">//判断元素是否存在</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>m MySet<span class="token punctuation">)</span> <span class="token function">isExist</span><span class="token punctuation">(</span>a <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token builtin">bool</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> m<span class="token punctuation">[</span>a<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">//返回set长度</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>m MySet<span class="token punctuation">)</span> <span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token builtin">int</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token function">len</span><span class="token punctuation">(</span>m<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">//设置值</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>m MySet<span class="token punctuation">)</span> <span class="token function">set</span><span class="token punctuation">(</span>a <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    m<span class="token punctuation">[</span>a<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token boolean">true</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">//删除值</span>
<span class="token keyword">func</span> <span class="token punctuation">(</span>m MySet<span class="token punctuation">)</span> <span class="token function">delete</span><span class="token punctuation">(</span>a <span class="token keyword">interface</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">delete</span><span class="token punctuation">(</span>m<span class="token punctuation">,</span> a<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment" spellcheck="true">//测试代码</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//创建一个set</span>
    <span class="token keyword">var</span> a MySet <span class="token operator">=</span> <span class="token function">make</span><span class="token punctuation">(</span>MySet<span class="token punctuation">)</span>
    <span class="token comment" spellcheck="true">//相当于</span>
    <span class="token comment" spellcheck="true">//var a MySet = make(map[interface{}]bool)</span>
    <span class="token comment" spellcheck="true">//打印set的长度</span>
    <span class="token comment" spellcheck="true">//fmt.Println(a.len())</span>
    <span class="token comment" spellcheck="true">//放入一个值</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token comment" spellcheck="true">//放入一个相同值</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"lqz"</span><span class="token punctuation">)</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"lqz"</span><span class="token punctuation">)</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"lqz"</span><span class="token punctuation">)</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"lqz"</span><span class="token punctuation">)</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"lqz"</span><span class="token punctuation">)</span>
    a<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span><span class="token string">"lqz"</span><span class="token punctuation">)</span>
    <span class="token comment" spellcheck="true">//打印长度，还是1</span>
    <span class="token comment" spellcheck="true">//fmt.Println(a.len())</span>
    <span class="token comment" spellcheck="true">//判断1是否存在</span>
    <span class="token comment" spellcheck="true">//fmt.Println(a.isExist(2))</span>
    <span class="token comment" spellcheck="true">////删除1</span>
    a<span class="token punctuation">.</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span>
    <span class="token comment" spellcheck="true">////判断1是否存在</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span><span class="token function">isExist</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>a<span class="token punctuation">.</span><span class="token function">len</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>

    <span class="token keyword">for</span> i<span class="token punctuation">,</span><span class="token boolean">_</span><span class="token operator">:=</span><span class="token keyword">range</span> a<span class="token punctuation">{</span>
        fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="5-make和new的区别"><a href="#5-make和new的区别" class="headerlink" title="5 make和new的区别"></a>5 make和new的区别</h3><pre class=" language-go"><code class="language-go"><span class="token keyword">package</span> main

<span class="token comment" spellcheck="true">//make和new的区别</span>
<span class="token keyword">type</span> PDuck1 <span class="token keyword">struct</span> <span class="token punctuation">{</span>
    name <span class="token builtin">string</span>
    sex <span class="token builtin">string</span>
    age <span class="token builtin">int</span>
<span class="token punctuation">}</span>
<span class="token keyword">func</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//make是引用类型初始化的时候用的</span>
    <span class="token comment" spellcheck="true">//var per *PDuck1 =new(PDuck1)    //new 是返回指向这个类型的指针</span>
    <span class="token comment" spellcheck="true">//fmt.Println(per)</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">//</span>
    <span class="token comment" spellcheck="true">//var per1 =&amp;PDuck1{}</span>
    <span class="token comment" spellcheck="true">//fmt.Println(per1)</span>

    <span class="token comment" spellcheck="true">//var per2 = make([]int,3,4)  //make是具体的造引用类型  //new是造指向这个类型的指针</span>
    <span class="token comment" spellcheck="true">//var per2 *[]int= new([]int)</span>
    <span class="token comment" spellcheck="true">//fmt.Println(per2)</span>
    <span class="token comment" spellcheck="true">//(*per2)=append((*per2),99)</span>
    <span class="token comment" spellcheck="true">//fmt.Println(per2)</span>
<span class="token punctuation">}</span></code></pre>
</div><div id="reward-container"><span class="hty-icon-button button-glow" id="reward-button" title="打赏" onclick="var qr = document.getElementById(&quot;qr&quot;); qr.style.display = (qr.style.display === &quot;none&quot;) ? &quot;block&quot; : &quot;none&quot;;"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-hand-coin-line"></use></svg></span><div id="reward-comment">点我就给你看点有意思的</div><div id="qr" style="display:none;"><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/alipay.png" alt="支付宝" title="支付宝"></a><div><span style="color:#00A3EE"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-alipay-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/qqpay.jpg" alt="QQ 支付" title="QQ 支付"></a><div><span style="color:#12B7F5"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-qq-line"></use></svg></span></div></div><div style="display:inline-block"><a target="_blank" rel="noopener" href="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg"><img loading="lazy" src="https://gitee.com/huang_zhao/hz/raw/master/hz/wxpay.jpg" alt="微信支付" title="微信支付"></a><div><span style="color:#2DC100"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-wechat-pay-line"></use></svg></span></div></div></div></div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者：</strong>爱肖彤真是太好了</li><li class="post-copyright-link"><strong>本文链接：</strong><a href="http://huang_zhao.gitee.io/task/2020/09/14/go/%E5%9F%BA%E7%A1%80/go%20%E7%BB%93%E6%9E%84%E4%BD%93%E3%80%81%E6%96%B9%E6%B3%95%E3%80%81%E6%8E%A5%E5%8F%A3/" title="go 结构体、方法、接口">http://huang_zhao.gitee.io/task/2020/09/14/go/%E5%9F%BA%E7%A1%80/go%20%E7%BB%93%E6%9E%84%E4%BD%93%E3%80%81%E6%96%B9%E6%B3%95%E3%80%81%E6%8E%A5%E5%8F%A3/</a></li><li class="post-copyright-license"><strong>版权声明：</strong>本博客所有文章除特别声明外，均默认采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" target="_blank" rel="noopener" title="CC BY-NC-SA 4.0 "><svg class="icon"><use xlink:href="#icon-creative-commons-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-by-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-nc-line"></use></svg><svg class="icon"><use xlink:href="#icon-creative-commons-sa-line"></use></svg></a> 许可协议。</li></ul></section></article><div class="post-nav"><div class="post-nav-item"><a class="post-nav-prev" href="/task/2020/09/15/%E5%89%8D%E7%AB%AF/Typescript%20%E7%B1%BB%EF%BC%8C%E7%BB%A7%E6%89%BF%EF%BC%8C%E4%BF%AE%E9%A5%B0%E7%AC%A6/" rel="prev" title="Typescript 类，继承，修饰符，静态，多态，抽象类"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-left-s-line"></use></svg><span class="post-nav-text">Typescript 类，继承，修饰符，静态，多态，抽象类</span></a></div><div class="post-nav-item"><a class="post-nav-next" href="/task/2020/09/14/%E5%89%8D%E7%AB%AF/Typescript%E5%87%BD%E6%95%B0/" rel="next" title="Typescript函数"><span class="post-nav-text">Typescript函数</span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-right-s-line"></use></svg></a></div></div></div></main><footer class="sidebar-translate" id="footer"><div class="copyright"><span>&copy; 2019 – 2022 </span><span class="with-love" id="animate"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-cloud-line"></use></svg></span><span class="author"> 爱肖彤真是太好了</span></div><div class="powered"><span>由 <a href="https://hexo.io" target="_blank" rel="noopener">Hexo</a> 驱动 v5.1.1</span><span class="footer-separator">|</span><span>主题 - <a rel="noopener" href="https://github.com/YunYouJun/hexo-theme-yun" target="_blank"><span>Yun</span></a> v0.9.7</span></div><div class="live_time"><span>本博客已萌萌哒地运行</span><span id="display_live_time"></span><span class="moe-text">(●'◡'●)</span><script>function blog_live_time() {
  window.setTimeout(blog_live_time, 1000);
  const start = new Date('2019-04-12T00:00:00');
  const now = new Date();
  const timeDiff = (now.getTime() - start.getTime());
  const msPerMinute = 60 * 1000;
  const msPerHour = 60 * msPerMinute;
  const msPerDay = 24 * msPerHour;
  const passDay = Math.floor(timeDiff / msPerDay);
  const passHour = Math.floor((timeDiff % msPerDay) / 60 / 60 / 1000);
  const passMinute = Math.floor((timeDiff % msPerHour) / 60 / 1000);
  const passSecond = Math.floor((timeDiff % msPerMinute) / 1000);
  display_live_time.innerHTML = " " + passDay + " 天 " + passHour + " 小时 " + passMinute + " 分 " + passSecond + " 秒";
}
blog_live_time();
</script></div><div id="busuanzi"><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><span id="busuanzi_container_site_uv" title="总访客量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-user-line"></use></svg></span><span id="busuanzi_value_site_uv"></span></span><span class="footer-separator">|</span><span id="busuanzi_container_site_pv" title="总访问量"><span><svg class="icon" aria-hidden="true"><use xlink:href="#icon-eye-line"></use></svg></span><span id="busuanzi_value_site_pv"></span></span></div></footer><a class="hty-icon-button" id="goUp" aria-label="back-to-top" href="#"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-arrow-up-s-line"></use></svg><svg class="progress-circle-container" viewBox="0 0 100 100"><circle class="progress-circle" id="progressCircle" cx="50" cy="50" r="48" fill="none" stroke="#0078E7" stroke-width="2" stroke-linecap="round"></circle></svg></a><a class="popup-trigger hty-icon-button icon-search" id="search" href="javascript:;" title="搜索"><span class="site-state-item-icon"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-search-line"></use></svg></span></a><script>window.addEventListener("DOMContentLoaded", () => {
  // Handle and trigger popup window
  document.querySelector(".popup-trigger").addEventListener("click", () => {
    document.querySelector(".popup").classList.add("show");
    setTimeout(() => {
      document.querySelector(".search-input").focus();
    }, 100);
  });

  // Monitor main search box
  const onPopupClose = () => {
    document.querySelector(".popup").classList.remove("show");
  };

  document.querySelector(".popup-btn-close").addEventListener("click", () => {
    onPopupClose();
  });

  window.addEventListener("keyup", event => {
    if (event.key === "Escape") {
      onPopupClose();
    }
  });
});
</script><script src="/task/js/search/local-search.js" defer></script><div class="popup search-popup"><div class="search-header"><span class="popup-btn-close close-icon hty-icon-button"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-close-line"></use></svg></span></div><div class="search-input-container"><input class="search-input" id="local-search-input" type="text" placeholder="搜索..." value=""></div><div id="local-search-result"></div></div></div><script defer src="/task/js/utils.js"></script><script defer src="/task/js/hexo-theme-yun.js"></script></body></html>